package com.test.cordova.util;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.content.FileProvider;
import android.text.TextUtils;
import android.util.Log;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.regex.Pattern;

import static android.app.Activity.RESULT_OK;

/**
 * 相机、图库
 * 图片处理
 */

public class FaceUtil {
    public final static int REQUEST_PICTURE_CHOOSE = 1;
    public final static int REQUEST_CAMERA_IMAGE = 2;
    public final static int REQUEST_CROP_IMAGE = 3;

    public static File mPictureFile;
    public static Bitmap mImage;

    /**
     * 从相册选择图片
     *
     * @param activity
     */
    public static void choosePhoto(Activity activity) {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_PICK);
        activity.startActivityForResult(intent, REQUEST_PICTURE_CHOOSE);
    }

    /**
     * 打开相机拍照
     *
     * @param activity
     * @return
     */
    public static void openCamera(Activity activity) {
        mPictureFile = new File(Environment.getExternalStorageDirectory(),
                "picture" + System.currentTimeMillis() / 1000 + ".jpg");
        // 启动拍照,并保存到临时文件
        Intent mIntent = new Intent();
        mIntent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
        mIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mPictureFile));
        mIntent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);
        activity.startActivityForResult(mIntent, REQUEST_CAMERA_IMAGE);


    }

    public interface OnPictureCropListener {
        void cropSuccess(Bitmap bitmap);

        void cropError(String errorMsg);
    }

    /**
     * 处理拍照、选择图片、裁剪的回调
     *
     * @param activity
     * @param requestCode
     * @param resultCode
     * @param data
     */
    public static void dealPic(final Activity activity, int requestCode, int resultCode, Intent data, final OnPictureCropListener cropListener) {
        if (resultCode != RESULT_OK) {
            Log.e("FaceUtil", "未完成");
            return;
        }
        Log.e("FaceUtil", "完成" + requestCode);
        String fileSrc = null;
        if (requestCode == REQUEST_PICTURE_CHOOSE) {

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                // Uri模型为content
                String[] proj = {MediaStore.Images.Media.DATA};
                Cursor cursor = activity.getContentResolver().query(data.getData(), proj,
                        null, null, null);
                cursor.moveToFirst();
                int idx = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                fileSrc = cursor.getString(idx);
                cursor.close();

            } else {
                // 有些低版本机型返回的Uri模式为file
                fileSrc = data.getData().getPath();
            }
            Uri fileUri = getImageUri(activity, fileSrc);
            // 跳转到图片裁剪页面
            cropPicture(activity, fileUri);
        } else if (requestCode == REQUEST_CAMERA_IMAGE) {
            if (null == mPictureFile) {
//                        showTip("拍照失败，请重试");
                Log.e("FaceUtil", "拍照失败，请重试");
                return;
            }
            Log.e("FaceUtil", "拍照成功");
            fileSrc = mPictureFile.getAbsolutePath();
//                    updateGallery(fileSrc);
            // 跳转到图片裁剪页面
            Log.e("FaceUtil", "跳转裁剪界面");
            Uri imageUri = getImageUri(activity, fileSrc);
            cropPicture(activity, imageUri);
        } else if (requestCode == FaceUtil.REQUEST_CROP_IMAGE) {

            Log.e("FaceUtil", "图片剪裁成功！" + Thread.currentThread().getName());
            // 获取返回数据
            final Bitmap bmp = data.getParcelableExtra("data");
            // 若返回数据不为null，保存至本地，防止裁剪时未能正常保存
            long start = System.currentTimeMillis();
            if (null != bmp) {
                FaceUtil.saveBitmapToFile(activity, bmp);
                Log.e("FaceUtil", "saveBitmapToFile :" + (System.currentTimeMillis() - start));
            }
            // 获取图片保存路径
            fileSrc = FaceUtil.getImagePath(activity);
            // 获取图片的宽和高
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            Log.e("FaceUtil", "图片信息路径！" + fileSrc);
            mImage = BitmapFactory.decodeFile(fileSrc, options);

            // 压缩图片
            Log.e("FaceUtil","wid::"+options.outWidth+" he::"+options.outHeight);
            //options.inSampleSize = 2;
            options.inSampleSize = Math.max(1, (int) Math.ceil(Math.max(
                    (double) options.outWidth / 1024f,
                    (double) options.outHeight / 1024f)));
            options.inJustDecodeBounds = false;
            mImage = BitmapFactory.decodeFile(fileSrc, options);
            Log.e("FaceUtil", "BitmapFactory :" + (System.currentTimeMillis() - start));
            // 若mImageBitmap为空则图片信息不能正常获取
            if (null == mImage) {
//                        showTip("图片信息无法正常获取！");
                Log.e("FaceUtil", "图片信息无法正常获取！");
                cropListener.cropError("图片信息无法正常获取！");
                return;
            }

            // 部分手机会对图片做旋转，这里检测旋转角度
            int degree = FaceUtil.readPictureDegree(fileSrc);
            if (degree != 0) {
                // 把图片旋转为正的方向
                mImage = FaceUtil.rotateImage(degree, mImage);
            }
            Log.e("FaceUtil", "rotateImage :" + (System.currentTimeMillis() - start));
            ByteArrayOutputStream baos = new ByteArrayOutputStream();

            //可根据流量及网络状况对图片进行压缩
            mImage.compress(Bitmap.CompressFormat.JPEG, 80, baos);
            Log.e("FaceUtil", "baos: " + (System.currentTimeMillis() - start));
            cropListener.cropSuccess(mImage);


        }
        mPictureFile = null;
        mImage = null;

    }



    /**
     * 处理拍照、选择图片的回调
     *
     * @param activity
     * @param requestCode
     * @param resultCode
     * @param data
     */
    public static void dealSelectPic(final Activity activity, int requestCode, int resultCode, Intent data, final OnPictureCropListener cropListener) {
        if (resultCode != RESULT_OK) {
            Log.e("FaceUtil", "未完成");
            return;
        }
        Log.e("FaceUtil", "完成" + requestCode);
        String fileSrc = null;
        if (requestCode == REQUEST_PICTURE_CHOOSE) {

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                // Uri模型为content
                String[] proj = {MediaStore.Images.Media.DATA};
                Cursor cursor = activity.getContentResolver().query(data.getData(), proj,
                        null, null, null);
                cursor.moveToFirst();
                int idx = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                fileSrc = cursor.getString(idx);
                cursor.close();

            } else {
                // 有些低版本机型返回的Uri模式为file
                fileSrc = data.getData().getPath();
            }
            // 压缩图片
            compressPic(activity,fileSrc,cropListener);
        } else if (requestCode == REQUEST_CAMERA_IMAGE) {

            if (null == mPictureFile) {
                Log.e("FaceUtil", "拍照失败，请重试");
                return;
            }
            Log.e("FaceUtil", "拍照成功");
            fileSrc = mPictureFile.getAbsolutePath();
            // 跳转到图片裁剪页面
            Log.e("FaceUtil", "跳转裁剪界面");
            compressPic(activity,fileSrc,cropListener);

        }
        mPictureFile = null;
        mImage = null;
    }

    private static void compressPic(Activity activity,String fileSrc, OnPictureCropListener cropListener) {
        long start = System.currentTimeMillis();
        // 获取图片的宽和高
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        Log.e("FaceUtil", "图片信息路径！" + fileSrc);
        BitmapFactory.decodeFile(fileSrc, options);

        // 压缩图片
        Log.e("FaceUtil","wid::"+options.outWidth+" he::"+options.outHeight);
        int height = ScreenUtil.getScreenHeightPixels(activity)/2;
        int width = ScreenUtil.getScreenWidthPixels(activity)/2;
        options.inSampleSize = calculateInSampleSize(options,height,width);
        options.inJustDecodeBounds = false;
        mImage = BitmapFactory.decodeFile(fileSrc, options);
        Log.e("FaceUtil", "BitmapFactory :" + (System.currentTimeMillis() - start));
        // 若mImageBitmap为空则图片信息不能正常获取
        if (null == mImage) {
//                        showTip("图片信息无法正常获取！");
            Log.e("FaceUtil", "图片信息无法正常获取！");
            cropListener.cropError("图片信息无法正常获取！");
            return;
        }

        // 部分手机会对图片做旋转，这里检测旋转角度
        int degree = FaceUtil.readPictureDegree(fileSrc);
        if (degree != 0) {
            // 把图片旋转为正的方向
            mImage = FaceUtil.rotateImage(degree, mImage);
        }
        Log.e("FaceUtil", "rotateImage :" + (System.currentTimeMillis() - start));
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        //可根据流量及网络状况对图片进行压缩
        mImage.compress(Bitmap.CompressFormat.JPEG, 80, baos);
        Log.e("FaceUtil", "baos: " + (System.currentTimeMillis() - start)+" size:"+ (baos.toByteArray().length / 1024) );
        cropListener.cropSuccess(mImage);
    }

    /**
     * 计算压缩比例值inSampleSize
     * @param options 压缩的参数设置
     * @param mHeight 想要的高度
     * @param mWidth 想要的宽度
     * @return
     */
    public static int calculateInSampleSize(BitmapFactory.Options options, int mHeight, int mWidth) {
        //原尺寸大小
        int yHeight = options.outHeight;
        int yWidth = options.outWidth;

        int inSampleSize = 1;
        //如果宽度大的话根据宽度固定大小缩放
        if (yWidth > yHeight && yWidth > mWidth) {
            inSampleSize = (int) (yWidth / mWidth);
        }
        //如果高度高的话根据宽度固定大小缩放
        else if (yWidth < yHeight && yHeight > mHeight) {
            inSampleSize = (int) (yHeight / mHeight);
        }
        if (inSampleSize <= 0)
            inSampleSize = 1;

        Log.e("FaceUtil","inSampLeSize:"+inSampleSize);
        return inSampleSize;
    }

        /**
         * 从7.0开始对外传递file://类型的uri会触发FileUriExposedException。因此，在分享私有文件时必须使用FileProvider
         *
         * @param activity
         * @param fileSrc
         * @return
         */
    private static Uri getImageUri(Activity activity, String fileSrc) {
        Uri fileUri;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            // Android 7.0 "file://" uri权限适配
            fileUri = FileProvider.getUriForFile(activity, "net.gdyuhui.wisdomcampd.provider", new File(fileSrc));
        } else {
            fileUri = Uri.fromFile(new File(fileSrc));
        }
        return fileUri;
    }

    /***
     * 裁剪图片
     * @param activity Activity
     * @param uri 图片的Uri
     */
    public static void cropPicture(Activity activity, Uri uri) {
        int outputY = ScreenUtil.getScreenHeightPixels(activity) / 4;
        int outputX = ScreenUtil.getScreenWidthPixels(activity) / 4;
        Intent innerIntent = new Intent("com.android.camera.action.CROP");
        innerIntent.setDataAndType(uri, "image/*");
        innerIntent.putExtra("crop", "true");// 才能出剪辑的小方框，不然没有剪辑功能，只能选取图片
        innerIntent.putExtra("aspectX", outputX); // 放大缩小比例的X
        innerIntent.putExtra("aspectY", outputY);// 放大缩小比例的X   这里的比例为：   1:1
        innerIntent.putExtra("outputX", outputX);  //这个是限制输出图片大小
        innerIntent.putExtra("outputY", outputY);
        innerIntent.putExtra("return-data", true);
        innerIntent.putExtra("circleCrop", false);
        // 切图大小不足输出，无黑框
        innerIntent.putExtra("scale", true);
        innerIntent.putExtra("scaleUpIfNeeded", true);
        Log.e("FaceUtil", "图片path:" + getImagePath(activity.getApplicationContext()));
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            // 加入访问权限
            innerIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
        File imageFile = new File(getImagePath(activity.getApplicationContext()));
//    File imageFile = new File(getImagePath(activity));
        innerIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(imageFile));
        innerIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        activity.startActivityForResult(innerIntent, REQUEST_CROP_IMAGE);
    }

    /**
     * 获得保存的图片的路径
     *
     * @return
     */
    public static String getImagePath(Context context) {
        return getImagePath(context, null);
    }

    /**
     * 获得保存的图片的路径  fileName 为 null 或 ""  返回的默认为 裁剪的图片路径
     *
     * @return
     */
    public static String getImagePath(Context context, String fileName) {
        String path;

        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            path = context.getFilesDir().getAbsolutePath();
        } else {
            path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/msc/";
        }

        if (!path.endsWith("/")) {
            path += "/";
        }

        File folder = new File(path);
        if (folder != null && !folder.exists()) {
            folder.mkdirs();
        }
        if (TextUtils.isEmpty(fileName)) {
            path += "ifd.jpg";
        } else {
            path += (fileName + ".jpg");
        }
        return path;
    }

    /**
     * 读取图片属性：旋转的角度
     *
     * @param path 图片绝对路径
     * @return degree 旋转角度
     */
    public static int readPictureDegree(String path) {
        int degree = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(
                    ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

    /**
     * 旋转图片
     *
     * @param angle  旋转角度
     * @param bitmap 原图
     * @return bitmap 旋转后的图片
     */
    public static Bitmap rotateImage(int angle, Bitmap bitmap) {
        // 图片旋转矩阵
        Matrix matrix = new Matrix();
        matrix.postRotate(angle);
        // 得到旋转后的图片
        Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
                bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        return resizedBitmap;
    }

    /**
     * 在指定画布上将人脸框出来
     *
     * @param canvas      给定的画布
     * @param face        需要绘制的人脸信息
     * @param width       原图宽
     * @param height      原图高
     * @param frontCamera 是否为前置摄像头，如为前置摄像头需左右对称
     * @param DrawOriRect 可绘制原始框，也可以只画四个角
     */
    static public void drawFaceRect(Canvas canvas, FaceRect face, int width, int height, boolean frontCamera, boolean DrawOriRect) {
        if (canvas == null) {
            return;
        }

        Paint paint = new Paint();
        paint.setColor(Color.rgb(255, 203, 15));
        int len = (face.bound.bottom - face.bound.top) / 8;
        if (len / 8 >= 2) paint.setStrokeWidth(len / 8);
        else paint.setStrokeWidth(2);

        Rect rect = face.bound;

        if (frontCamera) {
            int top = rect.top;
            rect.top = width - rect.bottom;
            rect.bottom = width - top;
        }

        if (DrawOriRect) {
            paint.setStyle(Paint.Style.STROKE);
            canvas.drawRect(rect, paint);
        } else {
            int drawl = rect.left - len;
            int drawr = rect.right + len;
            int drawu = rect.top - len;
            int drawd = rect.bottom + len;

            canvas.drawLine(drawl, drawd, drawl, drawd - len, paint);
            canvas.drawLine(drawl, drawd, drawl + len, drawd, paint);
            canvas.drawLine(drawr, drawd, drawr, drawd - len, paint);
            canvas.drawLine(drawr, drawd, drawr - len, drawd, paint);
            canvas.drawLine(drawl, drawu, drawl, drawu + len, paint);
            canvas.drawLine(drawl, drawu, drawl + len, drawu, paint);
            canvas.drawLine(drawr, drawu, drawr, drawu + len, paint);
            canvas.drawLine(drawr, drawu, drawr - len, drawu, paint);
        }

        if (face.point != null) {
            for (Point p : face.point) {
                if (frontCamera) {
                    p.y = width - p.y;
                }
                canvas.drawPoint(p.x, p.y, paint);
            }
        }
    }

    /**
     * 将矩形随原图顺时针旋转90度
     *
     * @param r      待旋转的矩形
     * @param width  输入矩形对应的原图宽
     * @param height 输入矩形对应的原图高
     * @return 旋转后的矩形
     */
    static public Rect RotateDeg90(Rect r, int width, int height) {
        int left = r.left;
        r.left = height - r.bottom;
        r.bottom = r.right;
        r.right = height - r.top;
        r.top = left;
        return r;
    }

    /**
     * 将点随原图顺时针旋转90度
     *
     * @param p      待旋转的点
     * @param width  输入点对应的原图宽
     * @param height 输入点对应的原图宽
     * @return 旋转后的点
     */
    static public Point RotateDeg90(Point p, int width, int height) {
        int x = p.x;
        p.x = height - p.y;
        p.y = x;
        return p;
    }

    public static int getNumCores() {
        class CpuFilter implements FileFilter {
            @Override
            public boolean accept(File pathname) {
                if (Pattern.matches("cpu[0-9]", pathname.getName())) {
                    return true;
                }
                return false;
            }
        }
        try {
            File dir = new File("/sys/devices/system/cpu/");
            File[] files = dir.listFiles(new CpuFilter());
            return files.length;
        } catch (Exception e) {
            e.printStackTrace();
            return 1;
        }
    }

    /**
     * 保存Bitmap至本地
     *
     * @param
     */
    public static void saveBitmapToFile(Context context, Bitmap bmp, String file_Name) {
        String file_path = "";
        if (TextUtils.isEmpty(file_Name)) {
            file_path = getImagePath(context, "ifd");
        } else {
            file_path = getImagePath(context, file_Name);
        }
        File file = new File(file_path);
        FileOutputStream fOut;
        try {
            fOut = new FileOutputStream(file);
            bmp.compress(Bitmap.CompressFormat.JPEG, 85, fOut);
            fOut.flush();
            fOut.close();
            Log.e("FaceUtil", "保存成功");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            bmp.recycle();
        }

    }

    /**
     * 保存Bitmap至本地    不带文件名时  默认为 从裁剪的图片文件  ifd.jpg
     *
     * @param
     */
    public static void saveBitmapToFile(Context context, Bitmap bmp) {
        saveBitmapToFile(context, bmp, null);
    }
}
